<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { BorderBox12 as DvBorderBox12, BorderBox7 as DvBorderBox7, Button as DvButton, Decoration2 as DvDecoration2 } from '@kjgl77/datav-vue3'
import EZUIKit from 'ezuikit-js'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'

interface IPlayer {
  play: () => Promise<any>;
  stop: () => Promise<any>;
  pause: () => Promise<void>;
  resume: (time: string) => Promise<any>;
  getOSDTime: () => Promise<any>;
  capturePicture: (name: string) => Promise<any>;
  startSave: (name: string) => Promise<any>;
  stopSave: () => Promise<any>;
  openSound: () => Promise<any>;
  closeSound: () => Promise<any>;
  destroy: () => Promise<any>;
  fullScreen: () => Promise<any>;
  cancelFullScreen: () => Promise<any>;
}

const message = useMessage()
const player = ref<IPlayer | null>(null)
const isPlaying = ref(true);
const isFullscreen = ref(false);
const isRecording = ref(false);
const snapshots = ref<string[]>([]); // 存储拍照图片URL
const recordingUrl = ref<string>(''); // 存储最新的录像URL
const playerReady = ref(false);
let reconnectAttempts = 0;
const maxReconnectAttempts = 3;
let fullscreenPlayer: IPlayer | null = null;
const router = useRouter();

// 添加接口返回类型定义
interface SensorData {
  id: string;
  name: string;
  value: number;
  timestamp: string;
}

interface CaptureResponse {
  code: number;
  message: string;
  data: {
    capture: {
      id: number;
      deviceSerial: string;
      picUrl: string;
      quality: number;
      captureTime: string;
    };
    sensorDataList: SensorData[];
  };
}

// 修改 token 接口返回类型定义
interface TokenResponse {
  code: number;
  message: string;
  data: {
    expireTime: string;
    accessToken: string;
  };
}

// 修改获取 token 的函数
const getAccessToken = async (): Promise<string> => {
  try {
    // 先尝试从 sessionStorage 获取摄像头 token
    const cameraToken = sessionStorage.getItem('cameraToken')
    if (cameraToken) {
      console.log('使用缓存的摄像头token')
      return cameraToken
    }

    // 获取认证 token
    const authToken = localStorage.getItem('token')
    if (!authToken) {
      console.error('未登录或token已失效')
      router.push('/login')
      throw new Error('未登录或token已失效')
    }

    console.log('开始获取摄像头token...')
    const response = await fetch('/api/camera/token', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${authToken}`
      }
    })

    // 检查响应状态
    if (!response.ok) {
      const errorText = await response.text()
      console.error('获取摄像头token失败:', {
        status: response.status,
        statusText: response.statusText,
        errorText
      })

      if (response.status === 401 || response.status === 403) {
        console.error('登录已过期，请重新登录')
        localStorage.removeItem('token')
        localStorage.removeItem('isLogin')
        sessionStorage.removeItem('cameraToken')
        router.push('/login')
        throw new Error('登录已过期，请重新登录')
      }
      throw new Error(`获取摄像头token失败: ${response.status} ${response.statusText}`)
    }

    const result = await response.json()
    console.log('摄像头token响应:', result)
    
    if (result.code === 200 && result.data?.accessToken) {
      console.log('获取摄像头token成功')
      // 保存摄像头token到sessionStorage
      const accessToken = result.data.accessToken
      sessionStorage.setItem('cameraToken', accessToken)
      return accessToken
    } else {
      throw new Error(result.message || '获取摄像头token失败')
    }
  } catch (err) {
    console.error('获取摄像头token失败:', err)
    throw err
  }
}

// 修改获取图片URL的函数
const getImageUrlWithToken = (url: string): string => {
  const token = localStorage.getItem('token')
  if (!token) {
    console.error('未登录或token已失效')
    return url
  }
  
  try {
    // 移除旧的token参数（如果有的话）
    const urlObj = new URL(url)
    urlObj.searchParams.delete('token')
    // 添加新的token
    urlObj.searchParams.append('token', token)
    return urlObj.toString()
  } catch (err) {
    console.error('URL处理失败:', err)
    return url
  }
}

// 播放/停止
const togglePlay = async () => {
  if (!playerReady.value || !player.value) {
    console.log('播放器未就绪')
    return
  }

  try {
    if (isPlaying.value) {
      await player.value.stop()
      isPlaying.value = false
    } else {
      await player.value.play()
      isPlaying.value = true
    }
  } catch (err) {
    console.error('播放控制失败:', err)
    initPlayer()
  }
}

// 全屏切换
const toggleFullscreen = async () => {
  if (!isFullscreen.value) {
    try {
      if (!player.value) {
        console.error('播放器未初始化');
        return;
      }
      
      // 使用原播放器进入全屏
      await player.value.fullScreen();
      isFullscreen.value = true;
    } catch (err) {
      console.error('进入全屏失败:', err);
    }
  } else {
    exitFullscreen()
  }
}

// 退出全屏
const exitFullscreen = async () => {
  try {
    if (player.value) {
      await player.value.cancelFullScreen();
    }
  } catch (err) {
    console.error('退出全屏失败:', err);
  }
  
  isFullscreen.value = false;
}

// 修改拍照功能
const takeSnapshot = async () => {
  if (!playerReady.value || !player.value) {
    console.log('播放器未就绪')
    return
  }

  try {
    // 获取认证 token
    const authToken = sessionStorage.getItem('token') || localStorage.getItem('token')
    if (!authToken) {
      console.error('未登录或token已失效')
      router.push('/login')
      return
    }

    // 调用新接口
    const response = await fetch('/api/camera/capture-with-sensors', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${authToken}`
      },
      body: JSON.stringify({
        quality: 3 // 使用1080P清晰度
      })
    })

    if (!response.ok) {
      if (response.status === 401 || response.status === 403) {
        console.error('登录已过期，请重新登录')
        localStorage.removeItem('token')
        localStorage.removeItem('isLogin')
        sessionStorage.removeItem('token')
        router.push('/login')
        return
      }
      throw new Error(`抓拍失败: ${response.status}`)
    }

    const result = await response.json()
    console.log('抓拍结果:', result)

    if (result.code === 200 && result.data?.capture?.picUrl) {
      const imageUrl = getImageUrlWithToken(result.data.capture.picUrl)
      snapshots.value.unshift(imageUrl)
      // 保存到 localStorage，但保存原始URL
      localStorage.setItem('snapshots', JSON.stringify([result.data.capture.picUrl]))
      console.log('抓拍成功，传感器数据:', result.data.sensorDataList)
    } else {
      throw new Error(result.message || '抓拍失败')
    }
  } catch (err) {
    console.error('抓拍失败:', err)
  }
}

// 在播放器错误处理函数中
const handleError = (err: any) => {
  console.log('播放器错误:', err)
  
  // 处理并发限制错误
  if (err.retcode === 9049) {
    message.warning('视频播放受限，请稍后重试')
    return
  }
  
  // 处理连接断开错误
  if (err.retcode === 1003) {
    message.error('视频连接断开，正在尝试重连...')
    // 可以添加重连逻辑
    setTimeout(() => {
      initPlayer()
    }, 5000) // 5秒后重试
    return
  }

  // 其他错误
  message.error(err.msg || '视频播放出错')
}

// 修改初始化播放器函数
const initPlayer = async () => {
  try {
    // 如果存在旧的播放器实例，先销毁
    if (player.value) {
      await player.value.destroy()
    }

    // 获取认证token
    const authToken = localStorage.getItem('token')
    if (!authToken) {
      throw new Error('未登录或token已失效')
    }

    // 获取摄像头token
    const accessToken = await getAccessToken()

    // 确保容器元素存在
    const container = document.getElementById('video-container')
    if (!container) {
      throw new Error('视频容器不存在')
    }

    // 初始化播放器
    player.value = new EZUIKit.EZUIKitPlayer({
      id: 'video-container',
      accessToken,
      url: 'ezopen://open.ys7.com/AC0174303/1.hd.live',
      template: 'simple',
      width: 1180,
      height: 480,
      autoplay: true,
      handleError,
      handleSuccess: () => {
        console.log('播放器初始化成功')
        playerReady.value = true
        isPlaying.value = true
      },
      env: {
        domain: 'https://open.ys7.com',
        enableSecurity: true,
        enableMetaprogramming: true
      },
      plugin: ['talk'],
      audio: true,
      controls: true,
      controlBar: {
        quality: true,
        audio: true,
        fullscreen: true
      }
    })
  } catch (error) {
    console.error('初始化播放器失败:', error)
    message.error(error instanceof Error ? error.message : '初始化播放器失败')
    
    if (error instanceof Error && error.message.includes('未登录')) {
      router.push('/login')
    }
  }
}

onMounted(async () => {
  // 等待 DOM 更新完成
  await nextTick()
  await initPlayer()
  
  // 从localStorage加载快照
  const savedSnapshots = localStorage.getItem('snapshots')
  if (savedSnapshots) {
    try {
      const urls = JSON.parse(savedSnapshots)
      snapshots.value = urls.map((url: string) => getImageUrlWithToken(url))
    } catch (err) {
      console.error('加载保存的快照失败:', err)
      snapshots.value = []
    }
  }
})

onBeforeUnmount(() => {
  if (player.value) {
    try {
      player.value.destroy();
    } catch (err) {
      console.error('销毁播放器失败:', err);
    }
  }
})

// 添加图片错误处理
const handleImageError = (event: Event, index: number) => {
  console.error('图片加载失败:', index)
  const img = event.target as HTMLImageElement
  const token = localStorage.getItem('token')
  
  if (!token) {
    console.error('未登录或token已失效')
    snapshots.value.splice(index, 1)
    return
  }

  // 尝试重新加载图片
  const originalUrl = img.src.split('?')[0]
  img.src = getImageUrlWithToken(originalUrl)
}

</script>

<template>
  <div class="middle-panel">
    <div class="content-wrapper">
      <DvBorderBox12 class="video-box">      
        <div class="video-wrapper">
          <div id="video-container"></div>
        </div> 
      </DvBorderBox12>
    </div>
    <div class="control-panel">
      <DvButton border="Border3" color="#1890ff" font-color="#fff" font-size="20px" @click="togglePlay">
        {{ isPlaying ? '停止' : '播放' }}
      </DvButton>
      <DvButton border="Border3" color="#1890ff" font-color="#fff" font-size="20px" @click="toggleFullscreen">
        {{ isFullscreen ? '退出全屏' : '全屏播放' }}
      </DvButton>
      <DvButton border="Border3" color="#1890ff" font-color="#fff" font-size="20px" @click="takeSnapshot">
        拍照
      </DvButton>
    </div>
    
    <div class="media-display">
      <DvBorderBox6 class="media-box" :color="['#00e0ff', '#00e0ff']">
        <div class="media-content">
          <div class="title-wrapper">
            <dv-decoration6 class="title-decoration" />
            <h3>拍照记录</h3>
            <dv-decoration6 class="title-decoration" />
          </div>
          <div class="snapshots-grid">
            <div v-for="(url, index) in snapshots" 
                :key="index" 
                class="snapshot-item">
              <img :src="url" alt="snapshot" @error="(e) => handleImageError(e, index)" loading="lazy" />
            </div>
          </div>
        </div>
      </DvBorderBox6>
    </div>
  </div>
</template>

<style scoped>
.content-wrapper {
  width: 1200px;
  height: 500px;
  display: flex;
  gap: 20px;
}

.media-display {
  display: flex;
  gap: 20px;
  width: 1200px;
}

.media-box {
  width: 1200px;
  height: 510px;
}

.media-content {
  width: 1200px;
  height: 510px;
  flex-direction: column;
  align-items: center;
  background: rgba(0, 24, 48, 0.6);
}

.title-wrapper {
  display: flex;  
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 20px 0;
}

.title-decoration {
  width: 200px;
  height: 40px;
}

h3 {
  color: #d9faff;
  margin: 0;
  font-size: 25px;
  text-align: center;
  font-weight: bold;
}

.snapshots-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  padding: 10px;
  width: 100%;
  height: 420px;
}

.snapshot-item {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 4px;
  background: transparent;
  display: flex;
  justify-content: center;
  align-items: center;
}

.snapshot-item img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  background: transparent;
  transition: transform 0.3s ease;
}

.snapshot-item:hover img {
  transform: scale(1.05);
}

.snapshot-item::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 30px;
  height: 30px;
  border: 3px solid rgba(255, 255, 255, 0.8);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  opacity: 0;
  z-index: 1;
}

.snapshot-item.loading::before {
  opacity: 1;
}

@keyframes spin {
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}

.recording-player {
  width: 100%;
  height: 100%;
  background: #000;
}

.no-recording {
  height: calc(100% - 30px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 16px;
}

.middle-panel {
  width: 100%;
  height: 100%;
  padding: 20px;
}

.video-box {
  width: 1200px;
  height: 500px;
}

.video-wrapper {
  width: 1180px;
  height: 480px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #000;
  border-radius: 10px;
  overflow: hidden;
  margin: 9px 10px;
}

#video-container {
  width: 100%;
  height: 100%;
}

.control-panel {
  font-size: 20px;
  margin-top: 10px;
  display: flex;
  justify-content: center;
  gap: 40px;
  background: #001529;
  padding: 15px 0;
}

.content-divider {
  width: 5px;
  height: 510px;
}

.recording-player {
  width: 100%;
  height: 100%;
  background: transparent;
  border-radius: 4px;
}

.no-recording {
  height: calc(100% - 30px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 16px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}

.video-controls {
  display: flex;
  justify-content: center;
  gap: 20px;
  padding: 10px 0;
}
</style>
